package com.polymathcoder.dpastry.core.util;

import com.polymathcoder.dpastry.api.Service;

/**
 * Abstract prototype for a Service Handle. To be paired with the ServiceContainer.
 *
 * @author Drew
 */
public abstract class ServiceHandle<T extends Service, C, K> {
    protected C container;
    protected K key;

    public ServiceHandle(C container, K key) {
        this.container = container;
        this.key = key;
    }

    /**
     * Return the contained service or fail-fast with a null
     *
     * @return the service held by this handle or null
     */
    public T get() {
        if (isAlive()) {
            try {
                return fetch();
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    /**
     * Get the Service from the Container without any safety checks!
     *
     * @return the service held by this handle
     */
    protected abstract T fetch();

    /**
     * Determines if the service still exists within the container
     *
     * @return whether the service is still held by the container
     */
    public abstract boolean isAlive();

    /**
     * Convenience method that destroys the service using whatever means
     * the container considers appropriate
     *
     * @return true if service destroyed
     */
    public abstract boolean destroy();

    /**
     * Convenience method that starts the service using whatever means
     * the container considers appropriate
     *
     * @return true if service is started
     */
    public abstract boolean start();

    /**
     * Convenience method that stops the service using whatever means
     * the container considers appropriate
     *
     * @return true if service is stopped
     */
    public abstract boolean stop();

    /**
     * Returns the container for the given service. Can be useful in many circumstances
     *
     * @return
     */
    public C container() {
        return container;
    }

}
